package org.feifei.hrm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.commons.lang.time.DateUtils;
import org.feifei.hrm.domain.KillCourse;
import org.feifei.hrm.mapper.KillCourseMapper;
import org.feifei.hrm.service.IKillCourseService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-01-20
 */
@Service
public class KillCourseServiceImpl extends ServiceImpl<KillCourseMapper, KillCourse> implements IKillCourseService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private KillCourseMapper killCourseMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void publishKillCourse2Redis() {
        //1 查询所有满足条件课程  待发布，在两天之内
        EntityWrapper<KillCourse> wrapper = new EntityWrapper<>();

        Date now = new Date();
        Date afterTwoDayTime = DateUtils.addDays(now, 2);
        wrapper.eq("kill_status",KillCourse.KILL_STATUS_WILL_PUBLISH)
                .and()
                .between("start_time",now,afterTwoDayTime);

        List<KillCourse> killCourses = killCourseMapper.selectList(wrapper);
        logger.info("查询到的课程，{}",killCourses);
        killCourses.forEach(killCourse -> {
            //2 生成秒杀码
            killCourse.setKillCode(UUID.randomUUID().toString());
            //3 课程信息redis缓存预热 K k json,如果存在了就不添加
            Boolean success = redisTemplate.opsForHash()
                    .putIfAbsent("kill_course", killCourse.getId().toString(), killCourse);
            if (success){
                logger.info("秒杀课程信息缓存预热成功，{}",killCourse.getCourseName());
                //4 课程信息库存redis缓存预热
                RSemaphore semaphore = redissonClient
                        .getSemaphore("kill_course_" + killCourse.getId());
                boolean success1 = semaphore.trySetPermits(killCourse.getKillCount());
                if (success1){
                    logger.info("秒杀课程库存缓存预热成功，{}",killCourse.getCourseName());
                    //5 修改数据库状态为已发布
                    killCourse.setKillStatus(KillCourse.KILL_STATUS_PUBLISHED);
                    killCourseMapper.updateById(killCourse);
                }else{
                    //失败了要把课程信息缓存信息回滚
                    logger.info("秒杀课程库存缓存预热失败，{}",killCourse.getCourseName());
                    redisTemplate.opsForHash().delete("kill_course",killCourse.getId().toString());
                }
            }
        });
    }
}
